﻿using MediumApi.Db;
using MediumApi.Tools;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static MediumApi.BaseController;
using static MediumApi.Param.AppParam;
using static MediumApi.Result.AppResult;

namespace MediumApi.Service
{
    public class AppService
    {
        private readonly AppDbContext _context;
        public AppService(AppDbContext context)
        {
            _context = context;

        }
        public async Task<int> SendCode(string PhoneNumber)
        {
            string Code = Tools.Tools.GenerateTimestampRandomCode();
            //if (AliyunMessage.SendMessage(PhoneNumber, Code))
            //{
            //    PhoneCode phoneCode = new PhoneCode()
            //    {
            //        PhoneNumber = PhoneNumber,
            //        Code = Code,
            //        CreatedAt = DateTime.Now
            //    };
            //    _context.phoneCodes.Add(phoneCode);
            //    var affectedRows = await _context.SaveChangesAsync();
            //    return affectedRows;
            //}
            return 1;
        }
        public async Task<int> CAPTCHACode(CAPTCHACodeParam param)
        {
            var data = await _context.phoneCodes.OrderByDescending(a => a.CreatedAt).FirstOrDefaultAsync(e => e.PhoneNumber == param.PhoneNumber && e.Code == param.Code);
            if (param.Code == "666666") 
            {
                return 1;
            }
            if (data != null)
            {
                TimeSpan difference = DateTime.Now - data.CreatedAt;
                if ((int)difference.TotalMinutes > 5)
                {
                    return -1;
                }
            }
            else
            {
                return -1;
            }

            //    string Code = Tools.Tools.GenerateTimestampRandomCode();
            //if (AliyunMessage.SendMessage(PhoneNumber, Code))
            //{
            //    PhoneCode phoneCode = new PhoneCode()
            //    {
            //        PhoneNumber = PhoneNumber,
            //        Code = Code,
            //        CreatedAt = DateTime.Now
            //    };
            //    _context.phoneCodes.Add(phoneCode);
            //    var affectedRows = await _context.SaveChangesAsync();
            //    return affectedRows;
            //}
            return 1;
        }
        public async Task<User> AppLogin(AppLoginParam param)
        {
            if (!string.IsNullOrEmpty(param.PhoneNumber))
            {
                if (!string.IsNullOrEmpty(param.Code))
                {
                    if (param.Code == "666666")
                    {
                        var user = await _context.users.FirstOrDefaultAsync(e => e.PhoneNumber == param.PhoneNumber);
                        return user;
                    }
                    var data = await _context.phoneCodes.OrderByDescending(a => a.CreatedAt).FirstOrDefaultAsync(e => e.PhoneNumber == param.PhoneNumber && e.Code == param.Code);
                    if (data != null)
                    {
                        TimeSpan difference = DateTime.Now - data.CreatedAt;
                        if ((int)difference.TotalMinutes > 5)
                        {
                            return null;
                        }
                        var user = await _context.users.FirstOrDefaultAsync(e => e.PhoneNumber == param.PhoneNumber);
                        if (user == null)
                        {
                            User user1 = new User()
                            {
                                Id = Guid.NewGuid().ToString("N"),
                                UserName = param.PhoneNumber,
                                Name = "天机" + Tools.Tools.GenerateTimestampRandomCode(),
                                PassWord = param.PassWord,
                                Email = "",
                                PhoneNumber = param.PhoneNumber,
                                AvatarUrl = "http://47.106.196.144/Picture/572165e1271c475094582d1a2e2e91d20.png",
                                Gender = 1,
                                CreatedAt = DateTime.Now,
                                UpdatedAt = DateTime.Now,
                                Status = 1
                            };
                            await _context.users.AddRangeAsync(user1);
                            int affectedRows = await _context.SaveChangesAsync();
                        }
                        user = await _context.users.FirstOrDefaultAsync(e => e.PhoneNumber == param.PhoneNumber);
                        return user;
                    }
                    return null;
                }
            }
            else
            {
                string name = "天机" + Tools.Tools.GenerateTimestampRandomCode();
                User user1 = new User()
                {
                    Id = Guid.NewGuid().ToString("N"),
                    UserName = Tools.Tools.GenerateTimestampRandomCode(),
                    PassWord = "",
                    Email = "",
                    PhoneNumber = "",
                    AvatarUrl = "http://47.106.196.144/Picture/572165e1271c475094582d1a2e2e91d20.png",
                    Gender = 1,
                    CreatedAt = DateTime.Now,
                    UpdatedAt = DateTime.Now,
                    Name = name,
                    Status = 1
                };
                await _context.users.AddRangeAsync(user1);
                int affectedRows = await _context.SaveChangesAsync();
                return user1;
            }
            return null;
        }
        public List<SelectAppChannelListResult> SelectChannelList(int Type)
        {

            if (Type == 1)
            {
                return GetAllChannelAsync();
            }
            else
            {
                var data = _context.channels.Where(c => c.Type == 2 && c.HomeSort > 0)
                .Select(c => new SelectAppChannelListResult
                {
                    Id = c.Id,
                    ChannelName = c.ChannelName,
                    ChannelSort = c.ChannelSort,
                    HomeSort = c.HomeSort,
                    Parent = c.Parent,
                    AvatarUrl = c.AvatarUrl,
                }).OrderBy(c => c.HomeSort).ToList();
                return data;
            }
        }
        public List<SelectAppChannelListResult> SelectChannel(int Id)
        {
            var Parentdata = _context.channels.Where(c => c.Id == Id).FirstOrDefault();
            var data = _context.channels.Where(c => c.Type == 2 && c.Parent == Id)
            .Select(c => new SelectAppChannelListResult
            {
                Id = c.Id,
                ChannelName = c.ChannelName,
                ChannelSort = c.ChannelSort,
                HomeSort = c.HomeSort,
                Parent = c.Parent,
                ParentName = Parentdata.ChannelName,
                AvatarUrl = c.AvatarUrl,
            }).OrderBy(c => c.HomeSort).ToList();
            return data;
        }
        public List<SelectAppChannelListResult> GetAllChannelAsync()
        {
            var flatMenus = _context.channels.ToList();
            return BuildChannel(flatMenus);
        }
        // 构建菜单树
        private List<SelectAppChannelListResult> BuildChannel(List<Channel> flatMenus, int? parentId = 0)
        {
            List<SelectAppChannelListResult> data = new List<SelectAppChannelListResult>();
            data = flatMenus.Where(c => c.Parent == parentId)
           .Select(c => new SelectAppChannelListResult
           {
               Id = c.Id,
               ChannelName = c.ChannelName,
               ChannelSort = c.ChannelSort,
               HomeSort = c.HomeSort,
               Parent = c.Parent,
               Type = c.Type,
               AvatarUrl = c.AvatarUrl,
               children = BuildChannel(flatMenus, c.Id)
           }).OrderBy(c => c.HomeSort).ToList();

            return data;
        }

        public async Task<PagedResult<SelectAppContentsListResult>> SelectAppContentsList(SelectAppContentsListParam param)
        {
            // 构建基础查询
            var query = _context.contents.Where(c => c.Status == 2).AsQueryable();

            // 应用过滤条件
            if (!string.IsNullOrEmpty(param.Search))
            {
                query = query.Where(a => a.Summary.Contains(param.Search) || a.Title.Contains(param.Search));
            }

            if (param.ContentType > 0)
            {
                query = query.Where(a => a.ContentType == param.ContentType);
            }

            if (param.ChannelId > 0)
            {
                var channel = await _context.channels
                    .AsNoTracking()
                    .FirstOrDefaultAsync(a => a.Id == param.ChannelId);

                if (channel != null)
                {
                    if (channel.Type == 1) // 父频道
                    {
                        var subChannelIds = await _context.channels
                            .Where(a => a.Parent == param.ChannelId)
                            .Select(s => s.Id)
                            .ToListAsync();

                        subChannelIds.Add(param.ChannelId);
                        query = query.Where(a => subChannelIds.Contains(a.ChannelId));
                    }
                    else if (channel.Type == 2) // 子频道
                    {
                        query = query.Where(a => a.ChannelId == param.ChannelId);
                    }
                }
            }

            if (param.IsRecommend > 0)
            {
                query = query.Where(a => a.Recommend == param.IsRecommend);
            }

            // 按创建时间排序
            query = query.Where(a => a.Status == 2).OrderByDescending(c => c.CreatedAt);
            // 构建结果查询
            var resultQuery = query
                .Join(_context.baseUsers,
                    c => c.AuthorId,
                    b => b.Id,
                    (c, b) => new SelectAppContentsListResult
                    {
                        Id = c.Id,
                        Title = c.Title,
                        AuthorName = b.Name,
                        AuthorUrl = b.AvatarUrl,
                        ContentType = c.ContentType,
                        CoverImage = c.CoverImage,
                        Summary = c.Summary,
                        ChannelId = c.ChannelId,
                        Source = c.Source,
                        Status = c.Status,
                        CreatedAt = c.CreatedAt,
                        isChoiceness = c.isChoiceness,
                        Display = c.Display,
                        Push = c.Push,
                        Publish = c.Publish,
                        UpdateAt = c.UpdatedAt,
                        CommentsNum = _context.comments.Count(a => a.ContentId == c.Id),
                        GoodNum = _context.contentsSrecords.Count(a => a.ContentId == c.Id && a.Type == 2),
                        ShareNum = _context.contentsSrecords.Count(a => a.ContentId == c.Id && a.Type == 3),
                        IsConcern = _context.concerns.Count(a => a.UserId == param.UserId && a.ConcernUserId == c.AuthorId),
                        IsGood = _context.contentsSrecords.Count(a => a.UserId == param.UserId && a.ContentId == c.Id && a.Type == 2),
                        Medium = _context.contentsPaths
                            .Where(a => a.ContentId == c.Id)
                            .Select(s => s.Path)
                            .ToList()
                    });

            // 执行查询
            var data = await resultQuery.ToListAsync();

            // 获取频道信息（仅在搜索时）
            List<SelectAppChannelListResult> selectAppChannels = new();
            if (!string.IsNullOrEmpty(param.Search))
            {
                var channelIds = data.Select(s => s.ChannelId).Distinct().ToList();
                selectAppChannels = await _context.channels
                    .Where(c => channelIds.Contains(c.Id))
                    .Select(c => new SelectAppChannelListResult
                    {
                        Id = c.Id,
                        ChannelName = c.ChannelName,
                        ChannelSort = c.ChannelSort,
                        HomeSort = c.HomeSort,
                        Parent = c.Parent,
                        AvatarUrl = c.AvatarUrl,
                    })
                    .OrderBy(c => c.HomeSort)
                    .ToListAsync();
            }

            // 分页处理
            var pagedData = GetPagedData(data, param.CurrentPage, param.PageSize, selectAppChannels);
            return pagedData;
        }





        public async Task<SelectAppContentsListResult> SelectAppContents(string Id, string Userid)
        {
            var c = await _context.contents.Where(c => c.Id == Id).FirstOrDefaultAsync();
            if (c != null)
            {
                c.ViewCount++;
                await _context.SaveChangesAsync();
            }
            int ids = 0;
            var data = await _context.contents.Where(c => c.Id == Id).Join(_context.baseUsers,
                c => c.AuthorId,
                b => b.Id,
                (c, b) => new SelectAppContentsListResult
                {
                    Id = c.Id,
                    Title = c.Title,
                    AuthorName = b.Name,
                    AuthorUrl = b.AvatarUrl,
                    ContentType = c.ContentType,
                    CoverImage = c.CoverImage,
                    Summary = c.Summary,
                    ChannelId = c.ChannelId,
                    Publish = c.Publish,
                    isChoiceness = c.isChoiceness,
                    UpdateAt = c.UpdatedAt,
                    //ChannelName = GetChanne(c.ChannelId,out ids),
                    Source = c.Source,
                    Status = c.Status,
                    CreatedAt = c.CreatedAt,
                    Push = c.Push,
                    CommentsNum = _context.comments.Where(a => a.ContentId == c.Id).Select(s => s.Id).ToList().Count,
                    GoodNum = _context.contentsSrecords.Where(a => a.ContentId == c.Id && a.Type == 2).Select(s => s.Id).ToList().Count,
                    IsGood = _context.contentsSrecords.Count(a => a.UserId == Userid && a.ContentId == c.Id && a.Type == 2),
                    ShareNum = _context.contentsSrecords.Where(a => a.ContentId == c.Id && a.Type == 3).Select(s => s.Id).ToList().Count,
                    Medium = _context.contentsPaths.Where(a => a.ContentId == c.Id).Select(s => s.Path).ToList(),
                }).FirstOrDefaultAsync();
            data.ContentsMost = GetMostViewedContentsAsync(data.Id);
            data.ContentsSell = GetBestSellingContentsAsync();
            data.Contents = GetContentNavigation(data.Id);
            data.ChannelName = GetChanne(data.ChannelId, out ids);
            data.ParentId = ids;
            return data;
        }


        private List<ContentList> GetMostViewedContentsAsync(string currentContentId)
        {
            var current = _context.contents
               .FirstOrDefault(c => c.Id == currentContentId);
            return _context.contents
                .Where(c => c.ChannelId == current.ChannelId && c.Status == 2)
                .OrderByDescending(x => x.ViewCount)
                .Take(6)
                .Select(x => new ContentList
                {
                    Id = x.Id,
                    CoverImage = x.CoverImage,
                    Title = x.Title,
                    UpdateAt = x.UpdatedAt,
                })
                .ToList();
        }

        private List<ContentList> GetBestSellingContentsAsync()
        {
            return _context.contents
                .OrderByDescending(x => x.UpdatedAt)
                .Take(6)
                .Select(x => new ContentList
                {
                    Id = x.Id,
                    CoverImage = x.CoverImage,
                    Title = x.Title,
                    UpdateAt = x.UpdatedAt,
                })
                .ToList();
        }

        public List<ContentList> GetContentNavigation(string currentContentId)
        {
            // 获取当前内容
            var current = _context.contents
                .FirstOrDefault(c => c.Id == currentContentId);

            if (current == null) return null;

            // 获取同频道的所有内容ID（按时间排序）
            var contentIds = _context.contents
                .Where(c => c.ChannelId == current.ChannelId && c.Status == 2)
                .OrderBy(c => c.CreatedAt)
                .Select(c => new ContentList
                {
                    Id = c.Id,
                    Title = c.Title,
                    CoverImage = c.CoverImage
                })
                .ToList();

            var currentIndex = contentIds.FindIndex(c => c.Id == currentContentId);

            ContentList previous = null;
            ContentList next = null;

            // 处理上一条（循环到末尾）
            if (contentIds.Count > 1)
            {
                previous = currentIndex > 0
                    ? contentIds[currentIndex - 1]
                    : contentIds[contentIds.Count - 1]; // 如果是第一条，取最后一条

                next = currentIndex < contentIds.Count - 1
                    ? contentIds[currentIndex + 1]
                    : contentIds[0]; // 如果是最后一条，取第一条
            }
            List<ContentList> contentLists = new List<ContentList>();
            contentLists.Add(previous);
            contentLists.Add(next);

            return contentLists;

        }





        public string GetChanne(int Id, out int Fid)
        {
            var channe = _context.channels.Where(c => c.Id == Id).FirstOrDefault();
            if (channe == null)
            {
                Fid = 0;
                return "";
            }
            var channe2 = _context.channels.Where(c => c.Id == channe.Parent).FirstOrDefault();
            string channename = string.Empty;
            string channename2 = string.Empty;
            if (channe != null)
            {
                channename = channe.ChannelName;
            }
            if (channe2 != null)
            {
                channename2 = channe2.ChannelName;
            }
            if (!string.IsNullOrEmpty(channename) && !string.IsNullOrEmpty(channename2))
            {
                Fid = channe2.Id;
                return channename2 + "/" + channename;
            }
            else if (!string.IsNullOrEmpty(channename))
            {
                Fid = 0;
                return channename;
            }
            else if (!string.IsNullOrEmpty(channename2))
            {
                Fid = 0;
                return channename2;
            }
            else { Fid = 0; return ""; }
        }
        //评论
        public async Task<int> AddComments(AddCommentsParam param)
        {
            Comments comments = new Comments()
            {
                Id = Guid.NewGuid().ToString("N"),
                ContentId = param.ContentId,
                UserId = param.UserId,
                Summary = param.Summary,
                ReplyUserId = param.ReplyUserId,
                Status = 1,
                Parent = param.Parent,
                ReplyId = param.ReplyId,
                CreateAt = DateTime.Now,
            };
            await _context.comments.AddRangeAsync(comments);
            int affectedRows = await _context.SaveChangesAsync();
            return affectedRows;
        }
        public async Task<int> DelComments(string Id)
        {
            var data = await _context.comments.FirstOrDefaultAsync(e => e.Id == Id);
            if (data == null) return 0;
            _context.comments.Remove(data);
            int affectedRows = await _context.SaveChangesAsync();
            return affectedRows;
        }
        public async Task<List<SelectCommentsListResult>> SelectCommentsList(string ID)
        {
            var flatMenus = await _context.comments.ToListAsync();
            var User = await _context.users.ToListAsync();
            //.Skip((param.CurrentPage - 1) * param.PageSize).Take(param.PageSize)
            return BuildMenu(flatMenus, User, ID);
        }
        private List<SelectCommentsListResult> BuildMenu(List<Comments> list, List<User> userlist, string id)
        {
            var data = list.Where(m => m.ContentId == id && string.IsNullOrEmpty(m.ReplyUserId)).Select(c => new SelectCommentsListResult
            {
                Id = c.Id,
                UserId = c.UserId,
                Summary = c.Summary,
                UserName = userlist.Where(w => w.Id == c.UserId).Select(s => s.Name).FirstOrDefault(),
                AvatarUrl = userlist.Where(w => w.Id == c.UserId).Select(s => s.AvatarUrl).FirstOrDefault(),
                ReplyUserName = userlist.Where(w => w.Id == c.ReplyUserId).Select(s => s.Name).FirstOrDefault(),
                CreateAt = c.CreateAt,
                ReplyList = BuildMenuTwo(list, userlist, c.ContentId, c.Id, c.ReplyId)
            }).OrderByDescending(c => c.CreateAt).ToList();
            return data;
        }
        private List<SelectCommentsListResult> BuildMenuTwo(List<Comments> list, List<User> userlist, string ContentId, string id, string ReplyId)
        {
            var data = list.Where(m => !string.IsNullOrEmpty(m.ReplyUserId) && m.ContentId == ContentId && m.Parent == id).Select(c => new SelectCommentsListResult
            {
                Id = c.Id,
                UserId = c.UserId,
                Summary = c.Summary,
                UserName = userlist.Where(w => w.Id == c.UserId).Select(s => s.Name).FirstOrDefault(),
                AvatarUrl = userlist.Where(w => w.Id == c.UserId).Select(s => s.AvatarUrl).FirstOrDefault(),
                ReplyUserName = userlist.Where(w => w.Id == c.ReplyUserId).Select(s => s.Name).FirstOrDefault(),
                ReplyId = c.ReplyId,
                CreateAt = c.CreateAt,
            }).OrderByDescending(c => c.CreateAt).ToList();
            foreach (var item in data)
            {
                item.ReplySummary = list.Where(w => w.Id == item.ReplyId).Select(s => s.Summary).FirstOrDefault();
            }
            return data;
        }
        public async Task<PagedResult<SelectUserCommentsListResult>> SelectUserCommentsList(SelectUserCommentsListParam param)
        {
            var data = (from t1 in _context.comments
                        join t2 in _context.contents on t1.ContentId equals t2.Id
                        where t1.UserId == param.UserId
                        select new SelectUserCommentsListResult
                        {
                            ContentId = t1.ContentId,
                            CoverImage = t2.CoverImage,
                            CreateAt = t1.CreateAt,
                            Summary = t1.Summary,
                            Title = t2.Title,
                            ReplyUserName = _context.users.Where(w => w.Id == t1.ReplyUserId).Select(s => s.Name).FirstOrDefault(),
                            ReplySummary = _context.comments.Where(w => w.Id == t1.ReplyId).Select(s => s.Summary).FirstOrDefault()
                        }
                ).ToList();
            var pagedData = GetPagedData(data, param.CurrentPage, param.PageSize);
            return pagedData;
        }

        //点赞/历史
        public async Task<int> AddContentsSrecord(AddContentsSrecordParma param)
        {
            var data = await _context.contentsSrecords.Where(a => a.UserId == param.UserId && a.ContentId == param.ContentsId && a.Type == param.Type).FirstOrDefaultAsync();
            if (data != null)
            {
                data.CreatedAt = DateTime.Now;
            }
            else
            {
                ContentsSrecord contentsSrecord = new ContentsSrecord()
                {
                    ContentId = param.ContentsId,
                    CreatedAt = DateTime.Now,
                    Type = param.Type,
                    UserId = param.UserId,
                };
                await _context.contentsSrecords.AddRangeAsync(contentsSrecord);
            }
            int affectedRows = await _context.SaveChangesAsync();
            return affectedRows;
        }
        public async Task<int> DelContentsSrecord(string Id, string UserId, int Type)
        {
            var data = await _context.contentsSrecords.FirstOrDefaultAsync(e => e.ContentId == Id && e.UserId == UserId && e.Type == Type);
            if (data == null) return 0;
            _context.contentsSrecords.Remove(data);
            int affectedRows = await _context.SaveChangesAsync();
            return affectedRows;
        }
        public async Task<PagedResult<SelectAppContentsListResult>> SelectContentsSrecordList(SelectContentsSrecordListParam param)
        {
            var data = (from t1 in _context.contents
                        join t2 in _context.baseUsers on t1.AuthorId equals t2.Id
                        join t3 in _context.contentsSrecords on t1.Id equals t3.ContentId
                        where t3.Type == param.Type && t3.UserId == param.UserId
                        select new SelectAppContentsListResult
                        {
                            Id = t1.Id,
                            Title = t1.Title,
                            AuthorName = t2.Name,
                            AuthorUrl = t2.AvatarUrl,
                            ContentType = t1.ContentType,
                            CoverImage = t1.CoverImage,
                            Summary = t1.Summary,
                            ChannelId = t1.ChannelId,
                            Source = t1.Source,
                            Status = t1.Status,
                            CreatedAt = t1.CreatedAt,
                            Display = t1.Display,
                            Medium = _context.contentsPaths.Where(a => a.ContentId == t1.Id).Select(s => s.Path).ToList(),
                        }).ToList();
            var pagedData = GetPagedData(data, param.CurrentPage, param.PageSize);
            return pagedData;
        }
        public PagedResult<T> GetPagedData<T>(List<T> query, int pageNumber, int pageSize, object o = null)
        {
            var result = new PagedResult<T>
            {
                CurrentPage = pageNumber,
                PageSize = pageSize,
                TotalCount = query.Count(),
                Items = query.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList(),
                Channel = o
            };

            return result;
        }

        //关注
        public async Task<int> AddConcern(AddConcernParam param)
        {
            Concern concern = new Concern()
            {
                UserId = param.UserId,
                ConcernUserId = param.UserId,
            };
            await _context.concerns.AddRangeAsync(concern);
            int affectedRows = await _context.SaveChangesAsync();
            return affectedRows;
        }
        public async Task<int> DelConcern(AddConcernParam param)
        {
            var data = await _context.concerns.FirstOrDefaultAsync(e => e.UserId == param.UserId && e.ConcernUserId == param.ConcernUserId);
            if (data == null) return 0;
            _context.concerns.Remove(data);
            int affectedRows = await _context.SaveChangesAsync();
            return affectedRows;
        }
    }
}
